package com.wind.common.aspect;

import cn.hutool.core.util.StrUtil;
import com.wind.common.utils.TraceLogContext;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 用于记录方法执行轨迹的日志切面类
 * 通过拦截标注了@TraceLog注解的方法，记录方法的进入和退出，以及维护traceId
 *
 * @author FengYin
 */
@Aspect
@Component
@Slf4j
@Data
public class TraceLogAspect {
    /**
     * 标记是否需要移除traceId
     */
    private boolean removeTraceId = false;

    /**
     * 在标注了@TraceLog注解的方法执行前调用
     * 检查并设置traceId，如果traceId为空，则进行设置，并标记需要在方法执行后移除traceId
     */
    @Before("@annotation(com.wind.common.annotation.TraceLog)")
    public void beforeMethodExecution() {
        String traceId = TraceLogContext.getTraceId();
        if (StrUtil.isBlank(traceId)) {
            TraceLogContext.setTraceId(traceId);
            removeTraceId = true;
        }
    }

    /**
     * 在标注了@TraceLog注解的方法执行后调用
     * 记录方法退出，并根据情况移除traceId
     */
    @After("@annotation(com.wind.common.annotation.TraceLog)")
    public void afterMethodExecution() {
        if (removeTraceId) {
            TraceLogContext.removeTraceId();
        }
    }
}
